package com.example.event_resource_java.authority.server.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.event_resource_java.authority.dao.CourseClassDao.StuClassDO;
import com.example.event_resource_java.authority.dao.ErrorBookDO;
import com.example.event_resource_java.authority.dao.PaperDao.ItemBankDO;
import com.example.event_resource_java.authority.dao.PaperDao.ItemPaperDao;
import com.example.event_resource_java.authority.mapper.ClassMapper;
import com.example.event_resource_java.authority.mapper.ErrorBookMapper;
import com.example.event_resource_java.authority.mapper.ItemBankMapper;
import com.example.event_resource_java.authority.server.ErrorBookService;
import com.example.event_resource_java.commons.domain.UserDO;
import com.example.event_resource_java.commons.model.ItemIdOptionBody;
import com.example.event_resource_java.commons.util.JWTUtil;
import com.example.event_resource_java.commons.vo.ErrorBookVO.ErrorBookSubmitVO;
import com.example.event_resource_java.commons.vo.ErrorBookVO.ErrorBookVO;
import com.example.event_resource_java.commons.vo.ErrorBookVO.UserStatisticErrorBookVO;
import com.example.event_resource_java.commons.vo.ExamPaperVO;
import com.example.event_resource_java.commons.vo.ExaminationQuestionVO;
import com.example.event_resource_java.commons.vo.PaperDetailVo;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.thymeleaf.util.ObjectUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class ErrorBookServiceImpl extends ServiceImpl<ErrorBookMapper, ErrorBookDO> implements ErrorBookService {

    @Resource
    private ErrorBookMapper errorBookMapper;
    @Resource
    private ItemBankMapper itemBankMapper;
    @Resource
    private ClassMapper classMapper;

    @Override
    public IPage<ErrorBookDO> teacherStatistic(ErrorBookDO errorBookDO) {
        QueryWrapper<ErrorBookDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(ObjectUtil.isNotEmpty(errorBookDO.getClassname()), "className", errorBookDO.getClassname());
        queryWrapper.eq(Objects.nonNull(errorBookDO.getTopicType()), "topic_type", errorBookDO.getTopicType());
        queryWrapper.like(ObjectUtil.isNotEmpty(errorBookDO.getTopicContent()), "topic_content", errorBookDO.getTopicContent());
        queryWrapper.gt("wrong_count", 0);
        queryWrapper.orderByDesc("wrong_count / answer_count").orderByDesc("wrong_count");

        IPage<ErrorBookDO> page = new Page<>(errorBookDO.getCurrent(), errorBookDO.getSize());
        IPage<ErrorBookDO> pageResult = errorBookMapper.selectPage(page, queryWrapper);

        // 计算正确率 错误率 正确数
        List<ErrorBookDO> errorBookDOList = pageResult.getRecords().stream().map(e -> {
            int rightCount = e.getAnswerCount() - e.getWrongCount();
            e.setRightCount(rightCount);

            double wrongRate = (double) e.getWrongCount() / e.getAnswerCount() == 0 ? 0 : (double) e.getWrongCount() / e.getAnswerCount();

            BigDecimal bigDecimal = new BigDecimal(1 - wrongRate);
            e.setRightRate(bigDecimal.setScale(4, BigDecimal.ROUND_DOWN).doubleValue());

            BigDecimal bigDecimal1 = new BigDecimal(wrongRate);
            e.setWrongRate(bigDecimal1.setScale(4, BigDecimal.ROUND_UP).doubleValue());
            return e;
        }).sorted(Comparator.comparingDouble(ErrorBookDO::getWrongRate).reversed()).collect(Collectors.toList());
        pageResult.setRecords(errorBookDOList);

        return pageResult;
    }

    @Override
    public List<UserStatisticErrorBookVO> userStatistic() {
        UserDO loginUser = JWTUtil.getUser();
        List<UserStatisticErrorBookVO> userStatisticErrorBookVOS = errorBookMapper.userStatistic(loginUser.getId());
        return userStatisticErrorBookVOS;
    }

    @Override
    public ExamPaperVO answer(Integer topicType) {
        Long userId = JWTUtil.getUser().getId();
        List<ItemBankDO> itemBankDOList = errorBookMapper.checkerAnswer(topicType, userId);

        List<ItemPaperDao> itemPaperDaoList = itemBankDOList.stream().map(itemBankDO -> {
            ItemPaperDao itemPaperDao = new ItemPaperDao();
            itemPaperDao.setOptions(itemBankDO.getOptions());
            itemPaperDao.setRightKey(itemBankDO.getRightKey().replaceAll(";;", ""));
            itemPaperDao.setId(itemBankDO.getId());
            itemPaperDao.setTopicContent(itemBankDO.getTopicContent());
            itemPaperDao.setTopicAnalysis(itemBankDO.getTopicAnalysis());
            itemPaperDao.setTopicTypes(itemBankDO.getTopicTypes());
            itemPaperDao.setOption(itemBankDO.getUserOption());
            return itemPaperDao;
        }).collect(Collectors.toList());

        ExamPaperVO examPaperVO = new ExamPaperVO();
        examPaperVO.setTemplateName("查看答案");

        if (topicType == 0) {
            examPaperVO.setSingle(itemPaperDaoList);
            examPaperVO.setJudge(new ArrayList<>());
            examPaperVO.setMultiple(new ArrayList<>());
        } else if (topicType == 1) {
            examPaperVO.setSingle(new ArrayList<>());
            examPaperVO.setJudge(new ArrayList<>());
            examPaperVO.setMultiple(itemPaperDaoList);
        } else if (topicType == 2) {
            examPaperVO.setSingle(new ArrayList<>());
            examPaperVO.setJudge(itemPaperDaoList);
            examPaperVO.setMultiple(new ArrayList<>());
        }

        return examPaperVO;
    }

    /**
     * 规程：随机100题练习
     *
     * @param topicType
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public PaperDetailVo practice(Integer topicType) {
        Long userId = JWTUtil.getUser().getId();
        List<ItemBankDO> practiceList = errorBookMapper.practice(topicType, userId);
        List<ExaminationQuestionVO> examinationQuestionVOList = practiceList.stream().map(itemBankDO -> {
            ExaminationQuestionVO examinationQuestionVO = new ExaminationQuestionVO();
            BeanUtils.copyProperties(itemBankDO, examinationQuestionVO);
//            examinationQuestionVO.setTopicTypes(topicType);
            return examinationQuestionVO;
        }).collect(Collectors.toList());


        PaperDetailVo paperDetailVo = new PaperDetailVo();
        paperDetailVo.setTemplateName("错题练习");
        if (topicType == 0) {
            paperDetailVo.setSingle(examinationQuestionVOList);
            paperDetailVo.setJudge(new ArrayList<>());
            paperDetailVo.setMultiple(new ArrayList<>());
        } else if (topicType == 1) {
            paperDetailVo.setSingle(new ArrayList<>());
            paperDetailVo.setJudge(new ArrayList<>());
            paperDetailVo.setMultiple(examinationQuestionVOList);
        } else if (topicType == 2) {
            paperDetailVo.setSingle(new ArrayList<>());
            paperDetailVo.setJudge(examinationQuestionVOList);
            paperDetailVo.setMultiple(new ArrayList<>());
        }
        return paperDetailVo;
    }

    /**
     * 正确设置状态为1 做题数增加
     *
     * @param errorBookSubmitVO
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public ExamPaperVO submit(ErrorBookSubmitVO errorBookSubmitVO) {
        Long userId = JWTUtil.getUser().getId();

        JSONArray answerJson = JSON.parseArray(errorBookSubmitVO.getAnswerString());
        JSONArray undoJson = JSON.parseArray(errorBookSubmitVO.getUndoString());
        List<ItemIdOptionBody> answerList = JSONArray.parseArray(answerJson.toJSONString(), ItemIdOptionBody.class);
        List<ItemIdOptionBody> undoList = JSONArray.parseArray(undoJson.toJSONString(), ItemIdOptionBody.class);
        ArrayList<ItemIdOptionBody> itemIdOptionBodyList = new ArrayList<>();
        itemIdOptionBodyList.addAll(answerList);
        itemIdOptionBodyList.addAll(undoList);

        List<ItemPaperDao> itemBankDOS = itemIdOptionBodyList.stream().map(itemIdOptionBody -> {
            ItemBankDO itemBankDO = itemBankMapper.selectById(itemIdOptionBody.getId());
            // 正确
            String options = itemIdOptionBody.getValue();
            if (ObjectUtil.equal(itemBankDO.getRightKey().replaceAll(";;", ""), options)) {
                ErrorBookDO errorBookDO = new ErrorBookDO();
                errorBookDO.setStatus(0);

                UpdateWrapper<ErrorBookDO> updateWrapper = new UpdateWrapper<>();
                updateWrapper.eq("user_id", userId);
                updateWrapper.eq("topic_id", itemBankDO.getId());
                updateWrapper.setSql("answer_count = answer_count + 1");
                errorBookMapper.update(errorBookDO, updateWrapper);
            } else {
                ErrorBookDO errorBookDO = new ErrorBookDO();
                errorBookDO.setUserOption(options);

                UpdateWrapper<ErrorBookDO> updateWrapper = new UpdateWrapper<>();
                updateWrapper.eq("user_id", userId);
                updateWrapper.eq("topic_id", itemBankDO.getId());
                updateWrapper.setSql("answer_count = answer_count + 1");
                updateWrapper.setSql("wrong_count = wrong_count + 1");
                updateWrapper.set("user_option", options);
                errorBookMapper.update(errorBookDO, updateWrapper);
            }

            ItemPaperDao itemPaperDao = new ItemPaperDao();
            BeanUtils.copyProperties(itemBankDO, itemPaperDao);
            itemPaperDao.setOption(options);
            return itemPaperDao;
        }).collect(Collectors.toList());

        Integer topicTypes = errorBookSubmitVO.getTopicType();
        ExamPaperVO examPaperVO = new ExamPaperVO();
        if (ObjectUtil.equal(topicTypes, 0)) {
            examPaperVO.setSingle(itemBankDOS);
            examPaperVO.setJudge(new ArrayList<>());
            examPaperVO.setMultiple(new ArrayList<>());
        } else if (ObjectUtil.equal(topicTypes, 1)) {
            examPaperVO.setSingle(new ArrayList<>());
            examPaperVO.setJudge(new ArrayList<>());
            examPaperVO.setMultiple(itemBankDOS);
        } else if (ObjectUtil.equal(topicTypes, 2)) {
            examPaperVO.setSingle(new ArrayList<>());
            examPaperVO.setJudge(itemBankDOS);
            examPaperVO.setMultiple(new ArrayList<>());
        }

        return examPaperVO;
    }
}
